package com.carey.blog.repository.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import org.json.JSONObject;

import com.carey.blog.framework.latke.Keys;
import com.carey.blog.framework.latke.repository.RepositoryException;
import com.carey.blog.framework.latke.repository.gae.AbstractGAERepository;
import com.carey.blog.model.Article;
import com.carey.blog.model.Sign;
import com.carey.blog.repository.ArticleSignRepository;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;

/**
 * Article-Sign relation Google App Engine repository.
 * 
 */
public final class ArticleSignGAERepository extends AbstractGAERepository
		implements ArticleSignRepository {

	/**
	 * Logger.
	 */
	private static final Logger LOGGER = Logger
			.getLogger(ArticleSignGAERepository.class.getName());

	@Override
	public String getName() {
		return Article.ARTICLE + "_" + Sign.SIGN;
	}

	@Override
	public List<JSONObject> getBySignId(final String signId)
			throws RepositoryException {
		final Query query = new Query(getName());
		query.addFilter(Sign.SIGN + "_" + Keys.OBJECT_ID,
				Query.FilterOperator.EQUAL, signId);
		query.addSort(Keys.OBJECT_ID, Query.SortDirection.DESCENDING);
		final PreparedQuery preparedQuery = getDatastoreService()
				.prepare(query);

		final List<JSONObject> ret = new ArrayList<JSONObject>();
		for (final Entity entity : preparedQuery.asIterable()) {
			final Map<String, Object> properties = entity.getProperties();
			final JSONObject e = new JSONObject(properties);

			ret.add(e);
		}

		return ret;
	}

	@Override
	public JSONObject getByArticleId(final String articleId)
			throws RepositoryException {
		final Query query = new Query(getName());
		query.addFilter(Article.ARTICLE + "_" + Keys.OBJECT_ID,
				Query.FilterOperator.EQUAL, articleId);
		final PreparedQuery preparedQuery = getDatastoreService()
				.prepare(query);

		final Entity entity = preparedQuery.asSingleEntity();
		if (null == entity) {
			return null;
		}

		final Map<String, Object> properties = entity.getProperties();

		return new JSONObject(properties);
	}

	/**
	 * Gets the {@link ArticleSignGAERepository} singleton.
	 * 
	 * @return the singleton
	 */
	public static ArticleSignGAERepository getInstance() {
		return SingletonHolder.SINGLETON;
	}

	/**
	 * Private default constructor.
	 */
	private ArticleSignGAERepository() {
	}

	/**
	 * Singleton holder.
	 * 
	 */
	private static final class SingletonHolder {

		/**
		 * Singleton.
		 */
		private static final ArticleSignGAERepository SINGLETON = new ArticleSignGAERepository();

		/**
		 * Private default constructor.
		 */
		private SingletonHolder() {
		}
	}
}
